﻿using Marmat.Forms;
using Marmat.Foundation;
using Marmat.FrameWork;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Marmat.Template.WinForm
{
    /// <summary>
    /// 
    /// </summary>
    public class AdvRelationGridImplement<Entity> : IProvider
    {
        private readonly AdvRelationGrid gridControl;
        private readonly Action<Entity[]> handle;
        private IAdvRelationProvider<Entity> relationProvider;

        /// <summary>
        /// 生成列集合触发的委托。
        /// </summary>
        public Action<SelectionRecordColumn> ColumnBuilder { get; set; }
        public Func<IEnumerable<Entity>> DataSource { get; set; }

        internal AdvRelationGridImplement(Marmat.Template.WinForm.AdvRelationGrid gridControl, Action<Entity[]> handle)
        {
            relationProvider = SystemCommand.GetService<IAdvRelationProvider<Entity>>();
            this.gridControl = gridControl;
            this.handle = handle;
            this.gridControl.CellNewRowLink += this.GridControl_CellNewRowLink;
        }

        private void GridControl_CellNewRowLink(object sender, EventArgs e)
        {
            var recordForm = SystemCommand.GetService<ISelectionRecordMultiPaginationForm<Entity>>();
            if (this.DataSource is not null)
                recordForm.DataSource = this.DataSource.Invoke();
            recordForm.Equals = (a, b) =>
            {
                MemberInfo member = typeof(Entity).GetMember(relationProvider.PrimaryName).FirstOrDefault();
                if (member is FieldInfo field)
                    return object.Equals(field.GetValue(a), field.GetValue(b));
                else if (member is PropertyInfo property)
                    return object.Equals(property.GetValue(a), property.GetValue(b));
                else
                    return false;
            };
            recordForm.ColumnBuilder = this.ColumnBuilder;
            recordForm.Search = (args) =>
            {
                string condition = args.Filter;
                if (!string.IsNullOrEmpty(condition) && !string.IsNullOrEmpty(this.gridControl.Filter))
                    condition = $"({this.gridControl.Filter}) And ({condition})";
                else if (!string.IsNullOrEmpty(this.gridControl.Filter))
                    condition = this.gridControl.Filter;
                var result = relationProvider.Load(condition, args.LoadPage, recordForm.LoadTop, string.Empty, out int totalCount);
                args.TotalCount = totalCount;
                return result;
            };
            if (recordForm.ShowDialog(out var rowCollection))
            {
                this.handle?.Invoke(rowCollection);
            }
        }
    }
}
